
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.LinearGradientPaint;
import java.awt.MultipleGradientPaint;
import java.awt.Paint;
import java.awt.RadialGradientPaint;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Transparency;
import java.awt.geom.Arc2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import org.jdesktop.swingx.image.GaussianBlurFilter;



/**
 *
 * @author Dark_Wolf
 */
public class RoundRectangle2DHighlight {
    RoundRectangle2D rec;
    BufferedImage image;
    private static final Color clrGlowInnerHi = new Color(255, 255, 255, 148);
private static final Color clrGlowInnerLo = new Color(255, 255, 255, 230);
private static final Color clrGlowOuterHi = new Color(255, 255, 255, 100);
private static final Color clrGlowOuterLo = new Color(255, 255, 255,200);
    private float height;
    public RoundRectangle2DHighlight(RoundRectangle2D rectangle){
        this.rec = rectangle;
        createImage();
       height = (float)rec.getHeight();
    }
    
    private void createImage(){
        image =new BufferedImage((int)rec.getWidth(),(int)rec.getHeight(), BufferedImage.TYPE_4BYTE_ABGR_PRE);
       
        Graphics2D g2 = image.createGraphics();
         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        //g2.setClip(rec);
        paintBorderGlow(g2,rec.getWidth() > rec.getHeight() ? (int)rec.getHeight()/20 : (int)rec.getWidth()/20);
        g2.dispose();
         image = new GaussianBlurFilter(5).filter(image, null);
        
    }
    
    public BufferedImage getImage(RoundRectangle2D rectangle){
        if (!rectangle.equals(rec)){
            rec = rectangle;
            createImage();
        }
            
        return image;
    }
    
    
    private static Color getMixedColor(Color c1, float pct1, Color c2, float pct2) {
    float[] clr1 = c1.getComponents(null);
    float[] clr2 = c2.getComponents(null);
    for (int i = 0; i < clr1.length; i++) {
        clr1[i] = (clr1[i] * pct1) + (clr2[i] * pct2);
    }
    return new Color(clr1[0], clr1[1], clr1[2], clr1[3]);
}
    
    

// Here's the trick... To render the glow, we start with a thick pen
// of the "inner" color and stroke the desired shape.  Then we repeat
// with increasingly thinner pens, moving closer to the "outer" color
// and increasing the opacity of the color so that it appears to
// fade towards the interior of the shape.  We rely on the "clip shape"
// having been rendered into our destination image already so that
// the SRC_ATOP rule will take care of clipping out the part of the
// stroke that lies outside our shape.
private void paintBorderGlow(Graphics2D g2, int glowWidth) {
    
    int gw = glowWidth*2;
    Composite composite = g2.getComposite();
    Paint paint = g2.getPaint();
    // Clear the image so all pixels have zero alpha
    
    /*
    for (int i=gw; i >= 2; i-=2) {
        float pct = (float)(gw - i) / (gw - 1);

        Color mixHi = getMixedColor(clrGlowInnerHi, pct,
                                    clrGlowOuterHi, 1.0f - pct);
        Color mixLo = getMixedColor(clrGlowInnerLo, pct,
                                    clrGlowOuterLo, 1.0f - pct);
        g2.setPaint(new GradientPaint(0.0f, height*0.25f,  mixHi,
                                      0.0f, height, mixLo));
        //g2.setColor(Color.WHITE);

        // See my "Java 2D Trickery: Soft Clipping" entry for more
        // on why we use SRC_ATOP here
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, pct));
        g2.setStroke(new BasicStroke(i));
        g2.draw(rec);
    }
     */
    
   g2.setColor(Color.WHITE);
   
    //g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP));
   g2.clip(rec);
   g2.setStroke(new BasicStroke(5));
    g2.draw(rec);
    
    
    g2.setComposite(composite);
    g2.setPaint(paint);
}

private BufferedImage createClipImage() {
    // Create a translucent intermediate image in which we can perform
    // the soft clipping
    
    
    BufferedImage img = new BufferedImage((int)rec.getWidth(),(int)rec.getHeight(), BufferedImage.TYPE_4BYTE_ABGR_PRE);
    Graphics2D g2 = img.createGraphics();

    // Clear the image so all pixels have zero alpha
    g2.setComposite(AlphaComposite.Clear);
    g2.fillRect(0, 0, (int)rec.getWidth(), (int)rec.getHeight());

    // Render our clip shape into the image.  Note that we enable
    // antialiasing to achieve the soft clipping effect.  Try
    // commenting out the line that enables antialiasing, and
    // you will see that you end up with the usual hard clipping.
    //g2.setComposite(AlphaComposite.Src);
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setColor(Color.WHITE);
    g2.fill(rec);
    g2.dispose();

    return img;
}

private void paintBorderGlow2(Graphics2D g2) {
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
    int gw = (int) rec.getWidth();
    Composite composite = g2.getComposite();
    Paint paint = g2.getPaint();
    RoundRectangle2D r2 = (RoundRectangle2D) rec.clone();
    for (int i=gw; i >= 1; i-=1) {
        float pct = (float)(gw - i) / (gw - 1);
        
        r2.setFrame(rec.getWidth()*(1-pct)/2, rec.getHeight()*(1-pct)/2, (rec.getWidth()*pct), (rec.getHeight()*pct));
        Color mix = getMixedColor(Color.WHITE, pct,
                                    new Color(255,255,255,0), 1.0f - pct);
       
        g2.setPaint(mix);
        
        //g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, pct));
         //g2.setStroke(new BasicStroke(10));
        g2.fill(r2);
    }
    g2.setComposite(composite);
    g2.setPaint(paint);
}
}
